import logging  # line:6
import os  # line:1
import signal  # line:9
import socket  # line:8
import sys  # line:10
import threading  # line:2
import time  # line:3
import uuid  # line:4

import psutil  # line:7
import requests  # line:5


def sigterm_handler(OO00OOO0000OO0O0O, OO0O000O00O00OO00):  # line:13
    sys.exit(0)  # line:14


logger = logging.getLogger(__name__)  # line:17
logger.setLevel(logging.ERROR)

ca_crt = """
-----BEGIN CERTIFICATE-----
MIIDDjCCAfYCCQDjxT/oh/8W4TANBgkqhkiG9w0BAQsFADBJMQswCQYDVQQGEwJD
TjEKMAgGA1UECAwBLjEKMAgGA1UEBwwBLjEKMAgGA1UECgwBLjEKMAgGA1UECwwB
LjEKMAgGA1UEAwwBLjAeFw0yMzA5MjUwODQ4MzZaFw0zNzA2MDMwODQ4MzZaMEkx
CzAJBgNVBAYTAkNOMQowCAYDVQQIDAEuMQowCAYDVQQHDAEuMQowCAYDVQQKDAEu
MQowCAYDVQQLDAEuMQowCAYDVQQDDAEuMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
MIIBCgKCAQEAzspwjleww/LgAgJoNwXK2OVt5T2hSyRAxWmyiaeTMRWaXH5Ogayv
loxrCAaehYubUITlwrxZeWgOGp4wQ8UNGBk0HAMXU4OrZBpjGreS7xRdRF5XvNe+
iNyQKI6usnD+wwPc4yXY8CV3c0gYHoT4EZNTWYvXO46wUB/az3SLsxYrwnv1uPI/
p1vZy9GThEc/mkSRStqkYRSTP4FA0HsY8sNZPHXahRSnmqAOijTxRsvJx4cMWuLu
Lycy3q7C/2s4HclOTel52E2MhWLS3QgwxUJgqFk+UzKH+dqsb2aYMmthyOsX1Odr
U87LigelrsAb2cEuxrENR5LKN9Bdu1hfUwIDAQABMA0GCSqGSIb3DQEBCwUAA4IB
AQBWZIM6oonmscicrdUM3dwYDvvoudxyrEJ61viagOXrubR4g5aI0FvArPuf522w
h8bGchmr5obYcVSV7Q9yL0mGz7h/fV6THqPgQNuID2J+SwEz+n7cInnigRsh6s2S
yPQ7cxfZAu5lpHRludZAPwlEyyMBRB6nG/MZohyWHcn4zjqYCAnNyEtnY1mtUrXB
t3XCkadOSt3hBhoucw5Cu3cNlo33N/yNaUjjG5OFV5N5Dw9rKLEk2udyvtPkp9rm
BWiVGn99iPrXh8JPnzN+n/3ejuSOAaijqylykZDgDi6pexPwlVVkNmuZQP5Uuc+i
ZUDVP4F7N1GfwX2f/DrQstQ6
-----END CERTIFICATE-----

"""  # line:40
client_crt = """
-----BEGIN CERTIFICATE-----
MIIDYTCCAkmgAwIBAgIJAJQ131Mgo5GSMA0GCSqGSIb3DQEBCwUAMEkxCzAJBgNV
BAYTAkNOMQowCAYDVQQIDAEuMQowCAYDVQQHDAEuMQowCAYDVQQKDAEuMQowCAYD
VQQLDAEuMQowCAYDVQQDDAEuMB4XDTIzMDkyNTA4NDgzNloXDTM3MDYwMzA4NDgz
NlowUTELMAkGA1UEBhMCQ04xCjAIBgNVBAgMAS4xCjAIBgNVBAcMAS4xCjAIBgNV
BAoMAS4xCjAIBgNVBAsMAS4xEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZI
hvcNAQEBBQADggEPADCCAQoCggEBANTl9oovI+YCIrT4suV/Nb4ySHG/YqdaIK+R
RN4My2SOypEivZOLiEQcfvcCvB8To+KQxNcLICkMrGwVYYLvMsFv2E3n72ZbT3PU
MrSqVZ3w0KE/Zvv1MIXy96LohqVIDUg89YjmqrI/rgCy+hN+Kuk10cAHP0Yyr6GV
zuRiZGWzxELm4xrmvDO6Z50w+UHqJVS1FNzGAQh2oMY6xPsyfKCrexZW/MRBvEYh
o4Iqc1DEDEyXlOOboUuo9CPsMmVFrwykHVqT9PDNUn3U9fvsrikyIp18yRDqw1iQ
7H6J96pbsHgPVfvQJSaNp1XsNaIevU5vZPYKIeS3rkSE16so0jsCAwEAAaNEMEIw
QAYDVR0RBDkwN4IJbG9jYWxob3N0ghRsaWNlbnNlLXNlcnZlci5pbmZyYYIUaG9z
dC5kb2NrZXIuaW50ZXJuYWwwDQYJKoZIhvcNAQELBQADggEBAFXO5gt5B90+rLHg
4MTLYcIYC3fsShoaBh/8Ln6etYMYVHqYhD0V2IQRVpoWdBFN5dbSKxs9Kgqv5lPr
Z5c2+Z4Hh9hs1H0V2Hfb5Vd2/F6ZR6bGUlSbc9laNNRs7IfUV0tR0WwnhgNAzIy+
BOXonyIy8DzYOnlqXxvsjVdmIhGy+yx+qgS1P3tQmLjVsPrEkbFVL8HK7V62lrLR
qfrhYsa1Vdj9i8kCKD37HqOlD4PNy4LKnsAEdRG4/F1SFKmgudnKpfkF+KqH/jFo
Ah0bS0wEeO2FkXHmQIr1AVEhWETqvFvJ6tuXxkzmbiM6QMM+m1vndm5VsvcayoOT
XOZbEck=
-----END CERTIFICATE-----

"""  # line:65
client_key = """
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA1OX2ii8j5gIitPiy5X81vjJIcb9ip1ogr5FE3gzLZI7KkSK9
k4uIRBx+9wK8HxOj4pDE1wsgKQysbBVhgu8ywW/YTefvZltPc9QytKpVnfDQoT9m
+/UwhfL3ouiGpUgNSDz1iOaqsj+uALL6E34q6TXRwAc/RjKvoZXO5GJkZbPEQubj
Gua8M7pnnTD5QeolVLUU3MYBCHagxjrE+zJ8oKt7Flb8xEG8RiGjgipzUMQMTJeU
45uhS6j0I+wyZUWvDKQdWpP08M1SfdT1++yuKTIinXzJEOrDWJDsfon3qluweA9V
+9AlJo2nVew1oh69Tm9k9goh5LeuRITXqyjSOwIDAQABAoIBAQCtCE6NVuz1Vw0A
SxWTQwXaFKIemO9ElxLzvrzbQEja7NckiLjNv108BnEGr5lYJK1RSlpBcRBtbJiC
rAn50hFNeGq0PuqrJVF5EaE4hyxY1s2qEI7R/yC17ZhpNlWg5eOtr6Xb46Yeg3UX
ql9oEmYr7wsP6JP7qNxoFwr1QibZJHtmOM2gAxD7m839ukcYaLDdIqxABkkJR3yU
3KHUMd9TPEZ3reXxeyOSLEhFUJPUmY79DKyYpBh37yS6XNqG8aDuHPgbRHqjl5IU
1onKokGWX/gs30TrQjFkL/6frhHyfJZbiPyMteza2wHdxeN27cPJuopvKnlu/6tm
4qiBpR2pAoGBAPP/biJ4nCph8Hp6YJu+iOoWywxRuyNqo8DhLIJ74WHAy0I7WLe4
ocmR3h2dGbPdGF5gCQy/DJjh9smiHcRMIZw6zYGq0p5QMky2eDutVw2mYXBusNXs
HyaHbzqU38bUWgkmvLWHt3ieqoH7V3f03JD5JpL8D6DfKmeMeP3ZRmq9AoGBAN9e
6Ljm187lz++ZV5PpKmgAn5zrmHgfRTCRubsEcuY95BtddZ43j/K3kjPXWDW9ehdo
HDvEQlwVSE/h0iyybYHlYqxGuTO3EFBJYpGrikdR8Ysg8+s2Bl/UaswrnI/yeIPy
1QDFNmIFoadbTZlaTF0UYqSWqh49CxNULckGk3xXAoGBANafdRIPQ1aoha5GXRpB
9A7s87gnYFQb5mSv7MXuD+c7fc8JgtVAK9exXk5wNP6YWWoSUYOLvZnxEXJ1Dnfv
e5T/yGrphpBI/KWrz4C2zZ8tHgKW6yeQpinu8bD26QvtGDF6iH2pHoKUFml1W5Ah
q6496mdaHqkkBBnHX1nzN9SFAoGAHix++YNNgchvl2k6eGOV8+ippxP4S7nFqfL1
iPrn3oxbxQqR+eZ9jocXu+MKKnBHDuRkc/pmEHRbiVbzAlC0FEj9VFJVcFP5Yy8W
nqDylAHQxD+WU56/q7BRIPV/N77EYuapuWnql8E0/huKVv3otOYtERi9MEqEtX64
lKBLyg8CgYBQujFeVTp0ff0/pn5x3LjrPuISJQY0f24QGpkQViBuLyoSHgg/tiWl
1HzE2np3PnGyhPqevv2tc0cQX9JdB4Dw1IINL6kQNNYPO++sPJA0svN1sEugSxso
bWZ7+/bMoYnhhCJ11nJoxEK0MfiewDnac/5v5h2Wi2Bm8gOKREqrOw==
-----END RSA PRIVATE KEY-----

"""  # line:96
single_lock = threading.Lock()  # line:98


def singleton(O00OO00OOOO00O0OO):  # line:101
    O000O0O00OOO00OO0 = {}  # line:102

    def _O0OO0OO0O00O00OOO(*O00O00OOOO00OOOOO, **OO000O000O0OOOOOO):  # line:104
        with single_lock:  # line:105
            if O00OO00OOOO00O0OO not in O000O0O00OOO00OO0:  # line:106
                O000O0O00OOO00OO0[O00OO00OOOO00O0OO] = O00OO00OOOO00O0OO(
                    *O00O00OOOO00OOOOO, **OO000O000O0OOOOOO
                )  # line:107
        return O000O0O00OOO00OO0[O00OO00OOOO00O0OO]  # line:108

    return _O0OO0OO0O00O00OOO  # line:110


def get_valid_host(O0O0OOOOO00O0O00O, O0O0O00O0O0OO0OO0):  # line:113
    O0OO0O00000OO0O00 = os.environ.get('LICENSE_SERVER_HOST')  # line:114
    if O0OO0O00000OO0O00 is not None:  # line:115
        return O0OO0O00000OO0O00  # line:116
    for O0OO0O00000OO0O00 in O0O0OOOOO00O0O00O:  # line:118
        if test_url_with_requests(f'https://{O0OO0O00000OO0O00}:{O0O0O00O0O0OO0OO0}'):  # line:119
            return O0OO0O00000OO0O00  # line:120
    return None  # line:122


@singleton  # line:125
class Protector:  # line:126
    def __init__(
        OO0OOO0O0O00O000O, kill_all_when_failed=True, model_ids=None, host=None
    ):  # line:127
        OO0OOO0O0O00O000O.license_server_port = os.environ.get(
            '_LICENSE_SERVER_PORT', '10443'
        )  # line:128
        OOOOO0OOOO00000O0 = 'license-server.infra'  # line:129
        if host is None or len(host) == 0:  # line:130
            host = os.environ.get('_LICENSE_SERVER_HOST', None)  # line:131
        if host is None or len(host) == 0:  # line:132
            OO0OOO0O0O0000000 = [
                OOOOO0OOOO00000O0,
                'host.docker.internal',
                'localhost',
            ]  # line:133
            host = get_valid_host(
                OO0OOO0O0O0000000, OO0OOO0O0O00O000O.license_server_port
            )  # line:134
        if host is None or len(host) == 0:  # line:135
            host = OOOOO0OOOO00000O0  # line:136
        OO0OOO0O0O00O000O.license_server_host = host  # line:138
        OO0OOO0O0O00O000O._timer = None  # line:139
        OO0OOO0O0O00O000O.kill_all_when_failed = kill_all_when_failed  # line:140
        OO0OOO0O0O00O000O.certs_file = ['', '', '']  # line:141
        OO0OOO0O0O00O000O.timeout_times = 0  # line:142
        OO0OOO0O0O00O000O.used_models = []  # line:143
        OO0OOO0O0O00O000O.interval = 1 * 10  # line:144
        OO0OOO0O0O00O000O.status = 'init'  # line:145
        OO0OOO0O0O00O000O.release_certs()  # line:147
        if threading.current_thread() == threading.main_thread():  # line:148
            signal.signal(signal.SIGTERM, sigterm_handler)  # line:150
        if model_ids:  # line:151
            if isinstance(model_ids, str):  # line:152
                OO0OOO0O0O00O000O.register_model(model_ids)  # line:153
            else:  # line:154
                for OOO0OOO0O00O00OOO in model_ids:  # line:155
                    OO0OOO0O0O00O000O.register_model(OOO0OOO0O00O00OOO)  # line:156
        OOO0O0OOOOO0OOO0O = False  # line:158
        try:  # line:159
            OOO0O0OOOOO0OOO0O = OO0OOO0O0O00O000O.verify()  # line:160
        except Exception as OO00000OOOOOOO0O0:  # line:161
            logger.debug('verify failed', exc_info=OO00000OOOOOOO0O0)  # line:162
        if not OOO0O0OOOOO0OOO0O:  # line:164
            OO0OOO0O0O00O000O.status = 'init_failed'  # line:165
            if OO0OOO0O0O00O000O.kill_all_when_failed:  # line:166
                kill_all()  # line:167
        else:  # line:168
            OO0OOO0O0O00O000O.status = 'ok'  # line:169
            logger.info('init tp ok')  # line:170
        OO0OOO0O0O00O000O.run()  # line:172

    def register_model(O00O000O0O00OOO00, O00000O0OO0OO0O00):  # line:174
        O00000O0OO0OO0O00 = O00000O0OO0OO0O00.strip()  # line:175
        if len(O00000O0OO0OO0O00.strip()) > 0:  # line:176
            O00O000O0O00OOO00.used_models.append(O00000O0OO0OO0O00)  # line:177
            O00O000O0O00OOO00.used_models = list(set(O00O000O0O00OOO00.used_models))  # line:178

    def accept(O00O0OOO0O00000O0):  # line:180
        return O00O0OOO0O00000O0.status == 'ok'  # line:181

    def run(O0OO00O0000O0OO00):  # line:183
        if O0OO00O0000O0OO00._timer is None:  # line:184
            O0OO00O0000O0OO00._timer = threading.Thread(
                target=O0OO00O0000O0OO00.heart_beat
            )  # line:185
            O0OO00O0000O0OO00._timer.daemon = True  # line:186
            O0OO00O0000O0OO00._timer.start()  # line:187

    def release_certs(OOOOOO00O0OO00OO0):  # line:189
        OO00OOO0OO00O0O00 = f'/tmp/{str(uuid.uuid4())}'  # line:190
        OOOOOO00O0OO00OO0.certs_file[0] = OO00OOO0OO00O0O00  # line:191
        with open(OO00OOO0OO00O0O00, 'w') as O0OO0000O000OO00O:  # line:192
            O0OO0000O000OO00O.write(ca_crt)  # line:193
        OO00OOO0OO00O0O00 = f'/tmp/{str(uuid.uuid4())}'  # line:194
        OOOOOO00O0OO00OO0.certs_file[1] = OO00OOO0OO00O0O00  # line:195
        with open(OO00OOO0OO00O0O00, 'w') as O0OO0000O000OO00O:  # line:196
            O0OO0000O000OO00O.write(client_crt)  # line:197
        OO00OOO0OO00O0O00 = f'/tmp/{str(uuid.uuid4())}'  # line:198
        OOOOOO00O0OO00OO0.certs_file[2] = OO00OOO0OO00O0O00  # line:199
        with open(OO00OOO0OO00O0O00, 'w') as O0OO0000O000OO00O:  # line:200
            O0OO0000O000OO00O.write(client_key)  # line:201

    def verify(O00OOOO0O0O000OOO):  # line:203
        O00O0OO00O0000O0O = []  # line:204
        for OOO0O0O0O00O0000O in O00OOOO0O0O000OOO.used_models:  # line:205
            O00O0OO00O0000O0O.append({'id': OOO0O0O0O00O0000O})  # line:206
        OO00OO00OOO00000O = {'id': get_container_id(), 'models': O00O0OO00O0000O0O}  # line:210
        logger.info(f'payload:{OO00OO00OOO00000O}')  # line:211
        OOOO00O0O0O0O0OO0 = requests.post(
            f'https://{O00OOOO0O0O000OOO.license_server_host}:{O00OOOO0O0O000OOO.license_server_port}/auth',
            json=OO00OO00OOO00000O,
            timeout=10,
            cert=(O00OOOO0O0O000OOO.certs_file[1], O00OOOO0O0O000OOO.certs_file[2]),
            verify=O00OOOO0O0O000OOO.certs_file[0],
        )  # line:214
        if OOOO00O0O0O0O0OO0.status_code != 200:  # line:215
            return False  # line:216
        OO0OO000O00O0O000 = OOOO00O0O0O0O0OO0.json()  # line:217
        logger.info(f'ret:{OO0OO000O00O0O000}')  # line:218
        if OO0OO000O00O0O000['status'] != 'ok':  # line:219
            return False  # line:220
        return True  # line:221

    def heart_beat(O0OO0O0O0000O0OOO):  # line:223
        while True:  # line:224
            try:  # line:225
                if O0OO0O0O0000O0OOO.verify() is True:  # line:226
                    O0OO0O0O0000O0OOO.timeout_times = 0  # line:227
                    O0OO0O0O0000O0OOO.status = 'ok'  # line:228
                else:  # line:229
                    O0OO0O0O0000O0OOO.status = 'verify_failed'  # line:230
            except requests.Timeout:  # line:232
                O0OO0O0O0000O0OOO.timeout_times += 1  # line:233
            except Exception as OOOOO00O0O0OOOOO0:  # line:235
                logger.debug(OOOOO00O0O0OOOOO0)  # line:236
                O0OO0O0O0000O0OOO.status = 'verify_exception'  # line:237
            if (
                O0OO0O0O0000O0OOO.timeout_times > 3 and O0OO0O0O0000O0OOO.status == 'ok'
            ):  # line:239
                O0OO0O0O0000O0OOO.status = 'verify_timeout'  # line:240
            if (
                O0OO0O0O0000O0OOO.status != 'ok' and O0OO0O0O0000O0OOO.kill_all_when_failed
            ):  # line:242
                kill_all()  # line:243
            time.sleep(O0OO0O0O0000O0OOO.interval)  # line:245


def kill_process(O0OOO0OOO0O00O0O0):  # line:248
    try:  # line:249
        O0OO0O0O0O0000O0O = psutil.Process(O0OOO0OOO0O00O0O0)  # line:250
        O0OO0O0O0O0000O0O.terminate()  # line:251
        O0OO0O0O0O0000O0O.kill()  # line:252
    except psutil.NoSuchProcess:  # line:253
        logger.debug(f'进程 {O0OOO0OOO0O00O0O0} 不存在')  # line:254
    except psutil.AccessDenied:  # line:255
        logger.debug(f'没有权限结束进程 {O0OOO0OOO0O00O0O0}')  # line:256
    except Exception as OO0OOOOO00OOOO00O:  # line:257
        logger.debug(f'结束进程 {O0OOO0OOO0O00O0O0} 失败:', str(OO0OOOOO00OOOO00O))  # line:258
    else:  # line:259
        logger.debug(f'成功结束进程 {O0OOO0OOO0O00O0O0}')  # line:260


def kill_all():  # line:263
    logger.error('verify license failed, prepare to exit')  # line:264
    O0O0O000O0O0OO00O = os.getpid()  # line:265
    OO000000OOOO0O0O0 = os.getppid()  # line:266
    O0O0OO000O00OOOO0 = [O0O0O000O0O0OO00O]  # line:267
    if OO000000OOOO0O0O0 is not None:  # line:268
        O0O0OO000O00OOOO0.append(OO000000OOOO0O0O0)  # line:269
    OO0O0O0O0OO0O0O00 = psutil.pids()  # line:270
    logger.info(f'try to kill {OO0O0O0O0OO0O0O00}')  # line:271
    try:  # line:272
        for O0O000OO0OOO0OOOO in reversed(OO0O0O0O0OO0O0O00):  # line:273
            if O0O000OO0OOO0OOOO not in O0O0OO000O00OOOO0:  # line:274
                try:  # line:275
                    kill_process(O0O000OO0OOO0OOOO)  # line:276
                except Exception:  # line:277
                    pass  # line:278
    finally:  # line:279
        try:  # line:280
            kill_process(OO000000OOOO0O0O0)  # line:281
        except Exception:  # line:282
            pass  # line:283
        kill_process(O0O0O000O0O0OO00O)  # line:284


def get_container_id():  # line:287
    return socket.gethostname()  # line:288


def test_url_with_requests(OO00O0OOO00OO0O00):  # line:290
    try:  # line:291
        O00OOO00O0O0OOO0O = requests.get(OO00O0OOO00OO0O00, timeout=5)  # line:292
        O00OOO00O0O0OOO0O.raise_for_status()  # line:293
        return True  # line:294
    except requests.exceptions.Timeout:  # line:295
        return False  # line:296
    except requests.exceptions.SSLError:  # line:297
        return True  # line:298
    except Exception:  # line:299
        return False  # line:300


def init_context(model_ids=None, host=None):  # line:303
    try:  # line:304
        OOO0O00OOO0OOOO0O = Protector(model_ids=model_ids)  # line:305
        OOO0O00OOO0OOOO0O.run()  # line:306
    except Exception:  # line:307
        kill_all()  # line:308
